package org.dei.perla.rockfall.utils.db;

import java.sql.PreparedStatement;
import java.sql.SQLException;

import org.dei.perla.parser.expressions.ConstantBlob;
import org.dei.perla.parser.expressions.ConstantCastException;
import org.dei.perla.parser.expressions.ConstantTimestamp;
import org.dei.perla.sys.dbutils.DBDumper;
import org.dei.perla.sys.device.fpc.dspic.DSPicFPC;
import org.dei.perla.sys.llqruntime.datastructures.Record;
import org.dei.perla.utils.logger.SimpleLogger;

public class DSPicDatabaseDump extends DBDumper {

	private PreparedStatement pStmBibiOnEvent;
	private PreparedStatement pStmAttitude;
	private PreparedStatement pStmTemperature;
	private PreparedStatement pStmCrackmeter;
	
	@Override
	protected void closeStatements() {
		try {
			this.pStmAttitude.executeBatch();
			this.pStmBibiOnEvent.executeBatch();
			this.pStmCrackmeter.executeBatch();
			this.pStmTemperature.executeBatch();
			conn.commit();
			this.pStmAttitude.close();
			this.pStmBibiOnEvent.close();
			this.pStmCrackmeter.close();
			this.pStmTemperature.close();	
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	@Override
	protected void initStatements() {
		try {
			pStmBibiOnEvent = conn.prepareStatement("INSERT INTO bibi " +
					"(ID_SENSORE, ID_NODO, TIMESTAMP, DATA, FLAGS, SAMPLES, MAGNITUDEX, MAGNITUDEY, " +
					"MAGNITUDEZ, PEAKX, PEAKY, PEAKZ, NOISEX, NOISEY, NOISEZ) " +
			"VALUES	(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
			pStmTemperature = conn.prepareStatement("INSERT INTO temperature " +
			"(ID_SENSORE, ID_NODO, TIMESTAMP, value) VALUES (?, ?, ?, ?)");
			pStmAttitude = conn.prepareStatement("INSERT INTO attitude " +
			"(ID_SENSORE, ID_NODO, TIMESTAMP, attitudeX, attitudeY, attitudeZ) VALUES (?, ?, ?, ?, ?, ?)");
			pStmCrackmeter = conn.prepareStatement("INSERT INTO crackmeter " +
			"(ID_SENSORE, ID_NODO, TIMESTAMP, crackmeter) VALUES (?, ?, ?, ?)");

		} catch (SQLException ex) {
			SimpleLogger.log(this.getClass(), "SQLException: " + ex.getMessage());
			SimpleLogger.log(this.getClass(), "SQLState: " + ex.getSQLState());
			SimpleLogger.log(this.getClass(), "VendorError: " + ex.getErrorCode());
		}
	}

	@Override
	protected void sendToDB(Record tRecord) {
		if (conn == null) {
			SimpleLogger.log(this.getClass(), "Impossibile memorizzare su DB, errore durante la connessione al DB");
			return;
		}
		try {
			String idNode = tRecord.getField("ID_NODO").getValueID();
			long timestamp = ((ConstantTimestamp)tRecord.getField("TIMESTAMP")).getValueTimestamp();
			if (tRecord.getField("ACQUISITION_TYPE").getValueInt() == DSPicFPC.CONTINUOUS) {
				pStmCrackmeter.setString(1, "CRACKMETER1_" + idNode);
				pStmCrackmeter.setString(2, idNode);
				pStmCrackmeter.setLong(3, timestamp);
				pStmCrackmeter.setInt(4, tRecord.getField("CRACKMETER1").getValueInt());
				this.pStmCrackmeter.addBatch();
		
				SimpleLogger.log(this.getClass(), "Added crackmeter record of node " + idNode);
				
				pStmTemperature.setString(1, "TEMPERATURE_" + idNode);
				pStmTemperature.setString(2, idNode);
				pStmTemperature.setLong(3, timestamp);
				pStmTemperature.setInt(4, tRecord.getField("TEMPERATURE").getValueInt());
				this.pStmTemperature.addBatch();
				
				SimpleLogger.log(this.getClass(), "Added temperature record of node " + idNode);
				
				pStmAttitude.setString(1, "ATTITUDE_" + idNode);
				pStmAttitude.setString(2, idNode);
				pStmAttitude.setLong(3, timestamp);
				pStmAttitude.setInt(4, tRecord.getField("ATTITUDEX").getValueInt());
				pStmAttitude.setInt(5, tRecord.getField("ATTITUDEY").getValueInt());
				pStmAttitude.setInt(6, tRecord.getField("ATTITUDEZ").getValueInt());
				this.pStmAttitude.addBatch();
				
				SimpleLogger.log(this.getClass(), "Added tilt record of node " + idNode);				
			} else if (tRecord.getField("ACQUISITION_TYPE").getValueInt() == DSPicFPC.ON_EVENT) {
				pStmBibiOnEvent.setString(1, "BIBI_" + idNode);
				pStmBibiOnEvent.setString(2, idNode);
				pStmBibiOnEvent.setLong(3, timestamp);
				pStmBibiOnEvent.setBytes(4, ((ConstantBlob)tRecord.getField("DATA")).getValueBlob());
				pStmBibiOnEvent.setInt(5, tRecord.getField("FLAGS").getValueInt());
				pStmBibiOnEvent.setInt(6, tRecord.getField("SAMPLES").getValueInt());
				pStmBibiOnEvent.setInt(7, tRecord.getField("MAGNITUDEX").getValueInt());
				pStmBibiOnEvent.setInt(8, tRecord.getField("MAGNITUDEY").getValueInt());
				pStmBibiOnEvent.setInt(9, tRecord.getField("MAGNITUDEZ").getValueInt());
				pStmBibiOnEvent.setInt(10, tRecord.getField("PEAKX").getValueInt());
				pStmBibiOnEvent.setInt(11, tRecord.getField("PEAKY").getValueInt());
				pStmBibiOnEvent.setInt(12, tRecord.getField("PEAKZ").getValueInt());
				pStmBibiOnEvent.setInt(13, tRecord.getField("NOISEX").getValueInt());
				pStmBibiOnEvent.setInt(14, tRecord.getField("NOISEY").getValueInt());
				pStmBibiOnEvent.setInt(15, tRecord.getField("NOISEZ").getValueInt());
				this.pStmBibiOnEvent.addBatch();
				SimpleLogger.log(this.getClass(), "Added event record of node " + idNode);				
			}

		} catch (SQLException e) {
			e.printStackTrace();
			SimpleLogger.log(this.getClass(), "Errore durante l'immissione dei dati nel DBl: " + e.getMessage());
		} catch (ConstantCastException e) {
			SimpleLogger.log(this.getClass(), "Errore durante l'immissione dei dati nel DB, " +
					"cast Constant non supportato: " + e.getMessage());
		}
	}
}
